<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div>
            <router-link to="/">首页</router-link>
            <router-link to="/goods">商品</router-link>
            <!-- 一级路由出口 -->
            <router-view></router-view>
        </div>
    </div>
    <script src="./vue-2.7.min.js"></script>
    <script src="./vue-router.js"></script>
    <script>
        // 1. 定义组件
        const Home = {
            template:'<div>这是首页</div>'
        }
        const Goods = {
            template:`
            <div>
                <h2>我是商品组件</h2>
                <router-link to="/goods/iphone/1">iPhone111</router-link>
                <router-link to="/goods/iphone/2">iPhone222</router-link>
                <router-link to="/goods/mac">Mac</router-link>
                <router-view></router-view>
            </div>
            `
        }

        // 二级路由组件 相当于就是一个.vue文件呀
        const Iphone = {
            data(){
                return {
                    msg:'123'
                }
            },
            created() {
                console.log('created---请求了数据了哦')
            },
            template:'<div>我是iphone</div>',

            // 1. beforeRouteEnter  在渲染该组件的对应路由被验证前调用
            // 1.1 不能获取this
            // 1.2 next函数可以传一个回调，接收vm参数， 唯一可以传回调函数的next

            beforeRouteEnter(to, from, next) {
                // 在渲染该组件的对应路由被验证前调用
                // 不能获取组件实例 `this` ！
                console.log('beforeRouteEnter')
                // console.log(this.msg)
                next((vm) => {
                    console.log(vm.msg)
                })
                // 因为当守卫执行时，组件实例还没被创建！
            },
            //  组件已经渲染好了，当我们动态切换路由的时候，并且匹配到的是同一个组件的时候
            //  路由在更新之前的守卫
            //  /iphone/2  ===> /iphone/1
            // beforeRouteUpdate, 可以在复用组件，路由动态切换，又需要向后端重新发送请求更新数据时
            // 可以在这里，重新请求数据，它可以获取到this 

            beforeRouteUpdate(to, from, next) {
                console.log('beforeRouteUpdate---------')
                next()
                // 在当前路由改变，但是该组件被复用时调用
                // 举例来说，对于一个带有动态参数的路径 `/users/:id`，在 `/users/1` 和 `/users/2` 之间跳转的时候，
                // 由于会渲染同样的 `UserDetails` 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
                // 因为在这种情况发生的时候，组件已经挂载好了，导航守卫可以访问组件实例 `this`
            },
            
            // beforeRouteLeave,
            // 在某一个组件内部，输入很多表单信息， 如果不小心点到了其他路由，一下子要跳转了
            // 我们可以在离开当前组件的路由之前，拦截 ，询问


            beforeRouteLeave(to, from, next) {
                // 在导航离开渲染该组件的对应路由时调用
                // 与 `beforeRouteUpdate` 一样，它可以访问组件实例 `this`
                if(window.confirm('你确定要离开吗？真的要离开吗？')){
                    next()
                } else {
                    next(false)
                }

            },
        }

        const Mac = {
            template:'<div>我是Mac</div>'
        }

        /* ====================  ===================== */
        const router = new VueRouter({
            routes:[
                {path:'/', component:Home},
                {
                    path:'/goods', 
                    component:Goods,
                    children:[
                        {path:'iphone/:id', component:Iphone},
                        {path:'mac', component:Mac},
                    ],
                    // 在配置路由的时候定义的守卫，只在进入当前路由之前触发 拦住
                    beforeEnter: (to, from, next) => {
                        // ...
                        console.log('beforeEnter')
                        next()
                    }
                },
            ]
        })

        // 一 全局守卫
        // 1. 全局前置守卫 router.beforeEach((to,from,next)=>{})
        // 2. 全局解析守卫 router.beforeResolve()
        // 3. 全局后置守卫 router.afterEach((to,from) =>{})    ==>它唯一没有next函数
        router.beforeEach((to,from,next)=>{
            console.log('beforeEach')
            next()
        })

        router.beforeResolve((to,from,next)=>{
            console.log('beforeResolve')
            next()
        })

        router.afterEach((to, from) => {
            // to and from are both route objects.
            console.log('afterEach')
            // console.log(to, from)
        })

        // 二 路由独享守卫 beforeEnter 
        // 在配置路由的时候定义的守卫，只在进入当前路由之前触发 拦住

        // 三 组件内守卫  ==> .vue文件中，配置的守卫，只对组件生效
        // 1. beforeRouteEnter
        // 2. beforeRouteUpdate 
        // 3. beforeRouteLeave

        const vm = new Vue({
            router,
        }).$mount('#app')


        // 导航守卫 
        // 全局守卫
        //    ==> router实例创建好之后   3个  router.beforeEach / router.beforeResolve / router.afterEach
        // 路由独享守卫
        //    ==> 配置单条路由规则的时候  1个  路由配置的时候定义的守卫  beforeEnter
        // 组件内的守卫   3个
        //  ==> .vue组件内 beforeRouteEnter   ==> 没有this   next(vm => {vm.msg})
        //                beforeRouteUpdate  ==> 动态路由切换，复用组件，如果想要重新请求数据
        //                beforeRouteLeave   ==> 在离开当前组件之前，询问一下，是否要离开呢





    </script>
</body>
</html>